之前的幾天在寫執行緒程式都是使用實作 Runnable 的方式,然後在主程式裡面呼叫 Thread start 的方式,使用這種做法會有一個缺點,就是當我們想要執行緒的執行結果回傳值時,沒辦法直接取得,因為 start 方法是 void。因此今天改使用 FutureTask 的方式來取得執行緒的值,先來寫一支 Sample Code 如下:
import java.util.concurrent.Callable;
public class Callable1 implements Callable<String> {
private String message;
private long sleepTimeMillis;
public Callable1(String message, long sleepTimeMillis) {
this.message = message;
this.sleepTimeMillis = sleepTimeMillis;
}
@Override
public String call() throws Exception {
Thread.sleep(sleepTimeMillis);
return this.message;
}
}
上面使用實作 Callable 的方式來實作執行緒程式,主要會接收二個參數 message 和 sleep 參數,sleep 的目的是用來測試呼叫 FtureTask 類別的 get 方法是否為阻塞。就是要等待一個執行緒的結果出來,程式才會繼續的往下執行。
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
public class Test {
public static void main(String args[]) throws Exception {
Callable1 callable1 = new Callable1("Message1", 2000L);
Callable1 callable2 = new Callable1("Message2", 1000L);
FutureTask<String> futureTask1 = new FutureTask<String>(callable1);
FutureTask<String> futureTask2 = new FutureTask<String>(callable2);
ExecutorService executor = Executors.newFixedThreadPool(2);
executor.execute(futureTask1);
executor.execute(futureTask2);
System.out.println(futureTask1.get());
System.out.println(futureTask2.get());
}
}
上面的程式是主程式的呼叫會先建立二個 callable 以及 futureTask 物件,然後呼叫 ExecutorService 類別去執行,最後會把執行緒執行的結果印出來。在這裡 futureTask1 的執行結果會先印出來,因為呼叫了 get 方法會被阻塞住。之後才會把 futureTask2 的值印出來。
程式執行的結果如下:
Message1
Message2
有關於 ExecutorService 的部份之後還會再介紹到。